package pfx;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.security.KeyFactory;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.PKCS8EncodedKeySpec;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;


/**
 *  1. pfx 是什么？
 *       pfx  是带有  私钥的证书文件，是符合 pkcs12标准的证书文件。
 *  2. keystore是什么 ？ 
 *       keystore 是 类似于证书库的存在，记录一条证书的信息，可以通过 指定算法，序列号、私钥、证书来产生。
 *  3. 跟 chain  有什么关系 ？
 *        还不清楚？？？
 *       
 * @author Administrator
 *
 */
public class Gen_pfx {
	/**
	 *  1. 获取 私钥  ------ 通过字符串经过 BASE64编码成 字节数组，然后通过 KeyFactory 转换成私钥
	 *  2. 获取 证书------- 通过 CertificateFactory 获取
	 *  3. 获取 keystore------- 通过指定的属性值来生成
	 *  4. 生成 pfx 证书 
	 *   
	 * @param args
	 * @throws Exception
	 */
	  public static void main(String[] args) throws Exception {
	      
	        //=====私钥Base64字符串转私钥对象
	        PrivateKey privateKey2 = getPrivateKey("MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIApSXeqcT3pKCBDKGpKqf+ByvrSdwMzDnmUb+6eVsms/GpbIhCHrGr+/fPRuq/COZuEsiNmkjusEeNgJCEoga/AzQ3xDklx6VZ7UDMfOVtK4KRsWHSMfYCtcXm2btppxcM6dOFwimtt1vPptgYfxsbdmtrxJw0ziccj0jAV4wpPAgMBAAECgYAHh+WMRZSv6aJ0+t1GGasRm4Pc5z8dDgP8uu8021MIOMUATuiahg5onyE3EYzhxQzziYGaOO3A2eSXMtAMrr+oCdwN7gqwjShgGkB/2cDvDnJ0wFHntvCYXjp13QEFJ8CO5fkYWLVxFtJ6VrdLUktUvhR+Fw4JLuTho/11lYdhGQJBAMFdi3RD2XEyoAoH4mkZ5siPfyW6gu5qkBBroAb3WJaAYxL0bwRmFYI+Q5YAmjYZwJlnm8AC3bMJREpFslP0NOUCQQCprNCXNQal6XuzyQGngy6eAOVGLKp/inGWyRW/wuFu6TJAGTAonbwTpNfeEfQ3aOJGgt/DHWOfvdVJ9BbraqMjAkEArX/2BRhsHrnCB74TVSK8hPDcsUms+af8I/+t0xJVFpWUUAmrI1NFsVuU4R8hP7HTstHYWm0359FEyS/IVrQkUQJAXaWG3t2iVLHf12OKaTTq5sPhxvBiDdCQTsOfIF5j474LQPtl7BTauBDUH7nTCz31HSugamTvFjxE2vNALyCE9wJAEE6G0W9IZDm6w+5nbiZ2mAhd0VBfMI2apa09/yMQGcqt2974bw/42chPoO9Vcwua+x3LsQ1stxl3+6jADQp7Fw==");
	        System.out.println("私钥Base64字符串2：" + Base64.encodeBase64String(privateKey2.getEncoded()));
	        
	        // ===导入证书数据
	        CertificateFactory cf = CertificateFactory.getInstance("X.509");
			X509Certificate certificate = (X509Certificate)cf.generateCertificate(new FileInputStream("C:\\Users\\Administrator\\Desktop\\ttt\\bankside1.cer"));
	        
	        //PFX：合成pfx（需要私钥、公钥证书）
	        String savePath = generatorPFX(privateKey2, certificate, "123456", new File("C:\\Users\\Administrator\\Desktop\\ttt\\bankside2501.pfx"));
	        System.out.println(savePath);
	    }  
	   /**
	     * 根据私钥Base64字符串获取私钥对象
	     * @param privateKeyStr
	     * @return
	     * @throws Exception
	     */
	  public static PrivateKey getPrivateKey(String privateKeyStr) throws Exception {
	      byte[] privateKeyByte = Base64.decodeBase64(privateKeyStr);
	      return getPrivateKey(privateKeyByte);
	  }
	  /**
	     * 根据私钥字节数组获取私钥对象
	     * @param privateKeyByte
	     * @return
	     * @throws Exception
	     */
	    public static PrivateKey getPrivateKey(byte[] privateKeyByte) throws Exception {
	        PrivateKey privateKey = null;
	        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyByte);
	        KeyFactory keyFactory = getKeyFactory("RSA");
	        privateKey = keyFactory.generatePrivate(keySpec);
	        return privateKey;
	    }
	  /**
	   * 获取指定算法的keyFactory
	   * @param algorithm
	   * @return
	   */
	 private static KeyFactory getKeyFactory(String algorithm) throws Exception {
	     KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
	     return keyFactory;
	 }
    /**
     * 根据私钥、公钥证书、密码生成pkcs12
     *
     * @param privateKey      私钥
     * @param x509Certificate 公钥证书
     * @param password        需要设置的密钥
     * @return
     * @throws Exception
     */
    public static byte[] generatorPkcx12(PrivateKey privateKey, X509Certificate x509Certificate, String password)
            throws Exception {
        Certificate[] chain = {x509Certificate};
        KeyStore keystore = KeyStore.getInstance("PKCS12");
        keystore.load(null, password.toCharArray());
        keystore.setKeyEntry(x509Certificate.getSerialNumber().toString(), privateKey, password.toCharArray(), chain);
        ByteArrayOutputStream bytesos = new ByteArrayOutputStream();
        keystore.store(bytesos, password.toCharArray());
        byte[] bytes = bytesos.toByteArray();
        return bytes;
    }
    /**
     * 根据私钥、公钥证书、密钥，保存为pfx文件
     *
     * @param privateKey      私钥
     * @param x509Certificate 公钥证书
     * @param password        打开pfx的密钥
     * @param saveFile        保存的文件
     * @return
     * @throws Exception
     */
    public static String generatorPFX(PrivateKey privateKey, X509Certificate x509Certificate, String password, File
            saveFile) throws Exception {
        //判断文件是否存在
        if (!saveFile.exists()) {
            //判断文件的目录是否存在
            if (!saveFile.getParentFile().exists()) {
                saveFile.getParentFile().mkdirs();
            }
            saveFile.createNewFile();
        }
        byte[] pkcs12Byte = generatorPkcx12(privateKey, x509Certificate, password);
        FileUtils.writeByteArrayToFile(saveFile, pkcs12Byte);
        return saveFile.getPath();
    }
}




